`include "defines.v"

module pc(

    input  wire                          clk,
    input  wire                          rst,  

    input  wire                          if_ready_i,   //axi
    input  wire [`AXI_DATA_WIDTH-1:0]    if_data_read_i,
    output wire                          if_valid_o,      
    output reg  [`AXI_ADDR_WIDTH-1:0]    if_addr_o,
    output      [1 : 0]                  if_size_o,

    input  wire                          jump_ena_i, 
    input  wire                          mem_req_i,   //pc_stall
    input  wire [`RAM_BUS]               new_pc_i, 
    input  wire                          clint_i, 
    input  wire                          ecall_i,
    input  wire                          mret_i,
    input  wire [`RAM_BUS]               mtvec_i, 
    input  wire [`RAM_BUS]               mepc_i, 
    output wire [`RAM_BUS]               pc_o,
    output wire [31 : 0]                 inst_o,
    output wire                          if_reg_valid_o

   
);

    reg  [63:0] pc;
    reg  [63:0] pc_next;
    wire if_hs_done;

    assign if_addr_o      = pc_next;
    assign pc_o           = pc_next;
    assign inst_o         = if_data_read_i[31:0];
    assign if_valid_o     = 1'b1;   
    assign if_size_o      = `SIZE_W;

    assign if_hs_done     = if_ready_i && if_valid_o;
    assign if_reg_valid_o = if_hs_done & ~mem_req_i;

    always @( posedge clk ) begin
        if (rst == `RST) begin
            pc <= `PC_START;
            pc_next <= `PC_START;
        end
        else if ( if_hs_done ) begin
            if (~mem_req_i)begin
                pc <= pc_next;
                pc_next <= pc_next + 4;
            end
            else begin
                pc <= pc;
                pc_next <= pc_next;
            end
        end
        else if(clint_i)
            pc_next <= mtvec_i;
        else if(jump_ena_i)
            pc_next <= new_pc_i;
        else if(ecall_i)
            pc_next <= mtvec_i;
        else if(mret_i)
            pc_next <= mepc_i;
        else begin
            pc <= pc;
            pc_next <= pc_next;
        end

    end


endmodule
